;;   This file is part of scheme-GNUnet, a partial Scheme port of GNUnet.
;;   Adapted from an iteration of (gnu gnunet metadata)
;;   Copyright (C) 2003, 2004, 2005, 2006, 2008, 2009, 2010 GNUnet e.V.
;;   Copyright (C) 2020 Maxime Devos <maxime.devos@student.kuleuven.be>
;;
;;   GNUnet is free software: you can redistribute it and/or modify it
;;   under the terms of the GNU Affero General Public License as published
;;   by the Free Software Foundation, either version 3 of the License,
;;   or (at your option) any later version.
;;
;;   GNUnet is distributed in the hope that it will be useful, but
;;   WITHOUT ANY WARRANTY; without even the implied warranty of
;;   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
;;   Affero General Public License for more details.
;;
;;   You should have received a copy of the GNU Affero General Public License
;;   along with this program.  If not, see <http://www.gnu.org/licenses/>.
;;
;;   SPDX-License-Identifier: AGPL-3.0-or-later
;;
;;   As a special exception to the GNU Affero General Public License,
;;   the file may be relicensed under any license used for
;;   most source code of GNUnet 0.13.1, or later versions, as published by
;;   GNUnet e.V.

;; Scheme port author: Maxime Devos
;; Scheme module: (gnu gnunet metadata struct)
;; Brief: meta data structure definitions
(library (gnu gnunet metadata struct)
  (export MetaDataHeader MetaDataEntry
	  MetaType MetaFormat)
  (import (only (gnu gnunet utils netstruct)
		structure/packed u32/big
		sizeof wrap-reader-setter
		offset)
	  (only (gnu extractor metaformats)
		integer->meta-format meta-format->integer)
	  (only (gnu extractor metatypes)
		integer->meta-type meta-type->integer)
	  (only (rnrs base) define-syntax assert =))

  (define-syntax MetaDataHeader
    (structure/packed
     ;; The version of the MD serialization.  The highest bit is used to
     ;; indicate compression.
     ;;
     ;; Version 0 is traditional (pre-0.9) meta data (unsupported)
     ;; Version is 1 for a NULL pointer
     ;; Version 2 is for 0.9.x (and possibly higher)
     ;; Other version numbers are not yet defined.
     ("version" u32/big)
     ;; How many MD entries are there?
     ("entries" u32/big)
     ;; Number of bytes of meta data
     ("size"    u32/big)))
  ;; This is followed by 'entries' values of type 'struct MetaDataEntry'
  ;; and then by 'entry' plugin names, mime-types and data blocks
  ;; as specified in those meta data entries.

  (assert (= (sizeof MetaDataHeader ()) 12))

  (define-syntax MetaType
    (wrap-reader-setter u32/big integer->meta-type meta-type->integer))
  (define-syntax MetaFormat
    (wrap-reader-setter u32/big integer->meta-format meta-format->integer))

  (assert (= (sizeof MetaType ()) 4))
  (assert (= (sizeof MetaFormat ()) 4))
  ;; catch some old issues
  (assert (= (offset MetaType ()) 0))
  (assert (= (offset MetaFormat ()) 0))
  (assert (= (offset MetaDataHeader ("version")) 0))
  (assert (= (offset MetaDataHeader ("entries")) 4))
  (assert (= (offset MetaDataHeader ("size")) 8))

  (define-syntax MetaDataEntry
    (structure/packed
     ;; Meta data type
     (type MetaType)
     ;; Meta data format (UTF8, binary, ...)
     (format MetaFormat)
     ;; Number of bytes in meta data.
     (data-size u32/big)
     ;; Number of bytes in the plugin name including 0-terminator.
     ;; 0 for no plugin name.
     (plugin-name-length u32/big)
     ;; Number of bytes in the mime type including 0-terminator.
     ;; 0 for NULL.
     (mime-type-length u32/big)))

  (assert (= (sizeof MetaDataEntry ()) 20)))
